﻿namespace DCHealthCheck.DomainModel {

    #region Usings
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    #endregion

    public class QuerySets {

        #region Members
        private readonly DCHealthCheckEntities dcHealthCheckEntities;

        #region IQueryable entity sets
        /// <summary>
        /// With included related entities.
        /// </summary>
        public IQueryable<Certificate> Certificates {
            get {
                return this.dcHealthCheckEntities.CertificateSet
                    .Include(x => x.SystemInfo)
                    .Include(x => x.SystemInfo.DomainController);
            }
        }

        /// <summary>
        /// Change-tracking disabled with included related entities.
        /// </summary>
        /// <remarks>Retrieving large collection of these would exhibit poor performance.</remarks>
        public IQueryable<DomainController> DomainControllers {
            get {
                return this.dcHealthCheckEntities.DomainControllerSet
                    .Include(x => x.SystemInfos)
                    .Include(x => x.SystemInfos.Select(y => y.GroupPolicySysvolInfo))
                    .Include(x => x.SystemInfos.Select(y => y.ProcessInfos))
                    .Include(x => x.SystemInfos.Select(y => y.ServiceInfos))
                    .Include(x => x.SystemInfos.Select(y => y.NetstatInfos))
                    .Include(x => x.SystemInfos.Select(y => y.RoleFeatures))
                    .Include(x => x.SystemInfos.Select(y => y.InstalledProducts))
                    .Include(x => x.SystemInfos.Select(y => y.TimeSyncInfo))
                    .Include(x => x.SystemInfos.Select(y => y.TagObjectValues))
                    .Include(x => x.SystemInfos.Select(y => y.TagObjectValues.Select(z => z.TagObject)))
                    .Include(x => x.SystemInfos.Select(y => y.ReplicationNeighbors))
                    .Include(x => x.SystemInfos.Select(y => y.PendingReplications));
                //.AsNoTracking<DomainController>();
            }
        }

        /// <summary>
        /// WithOUT included related entities.
        /// </summary>
        public IQueryable<DomainController> DomainControllersSlim {
            get {
                return this.dcHealthCheckEntities.DomainControllerSet
                    .AsQueryable<DomainController>();
                //.AsNoTracking<DomainController>();
            }
        }

        public IQueryable<DomainController> DomainControllersSlimNoTracking {
            get {
                return this.dcHealthCheckEntities.DomainControllerSet
                    .AsNoTracking<DomainController>();
            }
        }

        /// <summary>
        /// With included related entities.
        /// </summary>
        public IQueryable<GroupPolicySysvolInfo> GroupPolicySysvolInfos {
            get {
                return this.dcHealthCheckEntities.GroupPolicySysvolInfoSet
                    .Include(x => x.SystemInfo)
                    .Include(x => x.SystemInfo.DomainController);
                //.AsNoTracking<GroupPolicySysvolInfo>();
            }
        }

        public IQueryable<HealthCheckSummary> HealthCheckSummaries {
            get {
                return this.dcHealthCheckEntities.HealthCheckSummarySet
                    .Include(x => x.SystemInfos)
                    .Include(x => x.SystemInfos.Select(y => y.DomainController));
            }
        }

        /// <summary>
        /// With included related entities.
        /// </summary>
        public IQueryable<InstalledProduct> InstalledProducts {
            get {
                return this.dcHealthCheckEntities.InstalledProductSet
                    .Include(x => x.SystemInfo)
                    .Include(x => x.SystemInfo.DomainController);
                //.AsNoTracking<InstalledProduct>();
            }
        }

        public IQueryable<NetstatInfo> NetstatInfos {
            get {
                return this.dcHealthCheckEntities.NetstatInfoSet
                    .Include(x => x.SystemInfo)
                    .Include(x => x.SystemInfo.DomainController)
                    .Include(x => x.SystemInfo.ProcessInfos);
            }
        }

        /// <summary>
        /// With included related entities.
        /// </summary>
        public IQueryable<PendingReplication> PendingReplications {
            get {
                return this.dcHealthCheckEntities.PendingReplicationSet
                    .Include(x => x.SystemInfo)
                    .Include(x => x.SystemInfo.DomainController);
                //.AsNoTracking<PendingReplication>();
            }
        }

        /// <summary>
        /// With included related entities.
        /// </summary>
        public IQueryable<ProcessInfo> ProcessInfos {
            get {
                return this.dcHealthCheckEntities.ProcessInfoSet
                    .Include(x => x.SystemInfo)
                    .Include(x => x.SystemInfo.DomainController)
                    .Include(x => x.SystemInfo.ServiceInfos);
                //.AsNoTracking<ProcessInfo>();
            }
        }

        /// <summary>
        /// With included related entities.
        /// </summary>
        public IQueryable<ReplicationNeighbor> ReplicationNeighbors {
            get {
                return this.dcHealthCheckEntities.ReplicationNeighborSet
                    .Include(x => x.SystemInfo)
                    .Include(x => x.SystemInfo.DomainController);
                //.AsNoTracking<ReplicationNeighbor>();
            }
        }

        /// <summary>
        /// With included related entities.
        /// </summary>
        public IQueryable<ServiceInfo> ServiceInfos {
            get {
                return this.dcHealthCheckEntities.ServiceInfoSet
                    .Include(x => x.SystemInfo)
                    .Include(x => x.SystemInfo.DomainController)
                    .Include(x => x.SystemInfo.ProcessInfos);
                //.AsNoTracking<ServiceInfo>();
            }
        }

        /// <summary>
        /// With included related entities.
        /// </summary>
        public IQueryable<SystemInfo> SystemInfos {
            get {
                return this.dcHealthCheckEntities.SystemInfoSet
                    .Include(x => x.DomainController)
                    .Include(x => x.Certificates)
                    .Include(x => x.GroupPolicySysvolInfo)
                    .Include(x => x.ProcessInfos)
                    .Include(x => x.ServiceInfos)
                    .Include(x => x.InstalledProducts)
                    .Include(x => x.TimeSyncInfo)
                    .Include(x => x.TagObjectValues)
                    .Include(x => x.TagObjectValues.Select(y => y.TagObject))
                    .Include(x => x.ReplicationNeighbors)
                    .Include(x => x.PendingReplications)
                    .Include(x => x.NetstatInfos)
                    .Include(x => x.RoleFeatures);
                //.AsNoTracking<SystemInfo>();
            }
        }

        /// <summary>
        /// With only the DomainController included related entity.
        /// </summary>
        public IQueryable<SystemInfo> SystemInfosSlim {
            get {
                return this.dcHealthCheckEntities.SystemInfoSet
                    .Include(x => x.DomainController);
                //.AsNoTracking<SystemInfo>();
            }
        }

        public IQueryable<SystemInfo> SystemInfosSlimNoTracking {
            get {
                return this.dcHealthCheckEntities.SystemInfoSet
                    .Include(x => x.DomainController)
                    .AsNoTracking<SystemInfo>();
            }
        }

        /// <summary>
        /// WithOUT included related entities.
        /// </summary>
        /// <remarks>When retrieving a large number of TagObjects, including the TagObjectValues would be very slow.</remarks>
        public IQueryable<TagObject> TagObjects {
            get {
                return this.dcHealthCheckEntities.TagObjectSet;
                //.AsNoTracking<TagObject>();
            }
        }

        /// <summary>
        /// With included related entities.
        /// </summary>
        public IQueryable<TagObjectValue> TagObjectValues {
            get {
                return this.dcHealthCheckEntities.TagObjectValueSet
                    .Include(x => x.TagObject)
                    .Include(x => x.SystemInfo)
                    .Include(x => x.SystemInfo.DomainController);
                //.AsNoTracking<TagObjectValue>();
            }
        }

        /// <summary>
        /// With included related entities.
        /// </summary>
        public IQueryable<TimeSyncInfo> TimeSyncInfos {
            get {
                return this.dcHealthCheckEntities.TimeSyncInfoSet
                    .Include(x => x.SystemInfo)
                    .Include(x => x.SystemInfo.DomainController);
                //.AsNoTracking<TimeSyncInfo>();
            }
        }
        #endregion 
        #endregion

        #region Constructors
        private QuerySets() {

        }
        public QuerySets(DCHealthCheckEntities dcHealthCheckEntities) {
            this.dcHealthCheckEntities = dcHealthCheckEntities;
        }
        #endregion
    }
}
